package com.store.practice.service.impl;

import cn.hutool.core.util.StrUtil;
import com.store.practice.common.utils.JwtTokenUtil;
import com.store.practice.common.utils.VerificationCodeUtil;
import com.store.practice.mapper.AppAccountMapper;
import com.store.practice.model.AppAccount;
import com.store.practice.model.AppAccountExample;
import com.store.practice.service.BeauticianUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class BeauticianUserServiceImpl implements BeauticianUserService {
    private static final Logger logger = LoggerFactory.getLogger(BeauticianUserServiceImpl.class);

    @Autowired
    private AppAccountMapper accountMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private VerificationCodeUtil codeUtil;
    @Autowired
    private HttpServletRequest request;

    @Override
    public AppAccount getUserByPhone(Long num) {
        AppAccountExample example = new AppAccountExample();
        example.createCriteria().andPhoneEqualTo(num);
        List<AppAccount> appAccounts = accountMapper.selectByExample(example);
        if (appAccounts==null||appAccounts.size()==0){
            return null;
        }
        return appAccounts.get(0);
    }

    @Override
    public int insert(AppAccount account) {
        String encode = passwordEncoder.encode(account.getPassword());
        account.setPassword(encode);
        return accountMapper.insert(account);
    }

    @Override
    public int update(AppAccount account) {
        String encode = passwordEncoder.encode(account.getPassword());
        account.setPassword(encode);
        return accountMapper.updateByPrimaryKey(account);
    }

    @Override
    public Map login(Long num ,String password) {
        HashMap<String, Object> result = new HashMap<>();
        String username = num.toString();
        AppAccount user = getUserByPhone(num);
        if (user==null){
            throw new UsernameNotFoundException("对不起，该账户尚未注册");
        }
        if (user.getStatus()==0){
            throw new BadCredentialsException("该账号不可用");
        }
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        if (!passwordEncoder.matches(password,userDetails.getPassword())){
            logger.error("input password:{},userDetails password:{}",password,userDetails.getPassword());
            throw new BadCredentialsException("密码错误");
        }
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String token = jwtTokenUtil.generateToken(userDetails);
        result.put("accountInfo",user);
        result.put("token",token);
        return result;
    }

    @Override
    public String getCode(Long phone){
        if (phone.toString().length()!=11||!phone.toString().startsWith("1")){
            return "请输入正确的手机号码";
        }
        AppAccount user = getUserByPhone(phone);
        if (user!=null){
            return "对不起，该账号已注册";
        }
        String code = codeUtil.generateCode();
        HashMap<String, Object> map = new HashMap<>();
        map.put("phone",phone.toString());
        map.put("verificationCode",code);
        map.put("time",System.currentTimeMillis());
        request.getSession().setAttribute("verificationCode",map);
        logger.info("phone:{},code:{},time:{}",map.get("phone"),map.get("verificationCode"),map.get("time"));
        return "success";
    }

    @Override
    public int register(Long phone,String code,String password){
        Map map = (Map) request.getSession().getAttribute("verificationCode");
        if (!StrUtil.equals(phone.toString(),map.get("phone").toString())){
            return -1;
        }
        if (!StrUtil.equals(code.toUpperCase(),map.get("verificationCode").toString().toUpperCase())){
            return -2;
        }
        if ((Long) map.get("time")-System.currentTimeMillis()+60000<0){
            return -3;
        }
        AppAccount account = new AppAccount();
        account.setPassword(password);
        account.setPhone(phone);
        account.setStatus(1);
        insert(account);
        return account.getId();
    }

    @Override
    public int reset(Long account,String password1, String password2) {
        AppAccountExample example = new AppAccountExample();
        example.createCriteria().andPhoneEqualTo(account);
        List<AppAccount> appAccounts = accountMapper.selectByExample(example);
        if (appAccounts.size()==0){
            return -1;
        }
        AppAccount appAccount = appAccounts.get(0);
        if (!password1.equals(password2)){
            return -2;
        }
        appAccount.setPassword(passwordEncoder.encode(password1));
        return accountMapper.updateByPrimaryKey(appAccount);
    }
}
